package com.xinyan.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xinyan.config.RedisKeyConstant;
import com.xinyan.dto.UserDTO;
import com.xinyan.exception.InsertException;
import com.xinyan.exception.PasswordNotMatchException;
import com.xinyan.exception.UserNotFoundException;
import com.xinyan.exception.UsernameDuplicatedException;
import com.xinyan.pojo.SprayUsers;
import com.xinyan.mapper.SprayUsersMapper;
import com.xinyan.service.ISprayUsersService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author xzlf
 * @since 2024-03-19 17:57:43
 */
@Service
@Slf4j
public class SprayUsersServiceImpl implements ISprayUsersService {

    @Autowired
    private SprayUsersMapper sprayUsersMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Value("${redis.cache.userinfo.time}")
    private int timeout;

    @Override
    public void reg(SprayUsers users) {
        List<SprayUsers> sprayUsersList = sprayUsersMapper.selectList(new LambdaQueryWrapper<SprayUsers>()
                .eq(SprayUsers::getPhone, users.getPhone()));
        if (!CollectionUtils.isEmpty(sprayUsersList)) {
            throw new UsernameDuplicatedException("用户被占用");
        }
        String password = users.getPassword();
        String salt = UUID.randomUUID().toString();
        users.setSlat(salt);
        String md5Pwd = getMd5Pwd(password, salt);
        users.setPassword(md5Pwd);
        users.setStatus(1);
        String username = users.getUsername();
        if (StringUtils.isNotBlank(username)) {
            users.setCreateBy(username);
            users.setUpdateBy(username);
        }
        int insert = sprayUsersMapper.insert(users);
        if (insert == 0) {
            throw new InsertException("注册失败");
        }
    }

    private static String getMd5Pwd(String password, String salt) {
        return DigestUtils.md5DigestAsHex((salt + password + salt.toUpperCase()).getBytes(StandardCharsets.UTF_8));
    }

    @Override
    public UserDTO login(String phone, String password) {
        SprayUsers users = sprayUsersMapper.selectOne(new LambdaQueryWrapper<SprayUsers>()
                .eq(SprayUsers::getPhone, phone));
        if (users == null) {
            throw new UserNotFoundException("用户不存在");
        }

        // 判断查询结果中的status是否为1
        if (!(users.getStatus() == 1)) {
            // 否：抛出UserNotFoundException异常
            throw new UserNotFoundException("用户数据不存在的错误");
        }
        String slat = users.getSlat();
        String md5Pwd = getMd5Pwd(password, slat);

        if (!md5Pwd.equals(users.getPassword())) {
            throw new PasswordNotMatchException("密码验证错误");
        }
        // redis操作
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(users, userDTO);
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String key = RedisKeyConstant.USER_HEAD + uuid;
        redisTemplate.opsForValue().set(key, userDTO);
        redisTemplate.expire(key, timeout, TimeUnit.MINUTES);
        log.info("设置了hash可以过期时间：{} m,uuid为：{}", timeout, uuid);
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = requestAttributes.getResponse();
        response.setHeader(RedisKeyConstant.USER_RESPONSE_HEAD, uuid);
        return userDTO;
    }


    @Override
    public UserDTO findUserInfoByUUID(String header) {
        Object obj = redisTemplate.opsForValue().get(RedisKeyConstant.USER_HEAD + header);
        if (Objects.nonNull(obj)) {
//            log.info("进入了转换层=====");
            UserDTO users = JSON.parseObject(JSON.toJSONString(obj), UserDTO.class);
            return users;
        }
        return null;
    }

    @Override
    public UserDTO deleteUserInfoByUUID(String header) {
        Object obj = redisTemplate.opsForValue().getAndDelete(RedisKeyConstant.USER_HEAD + header);
        if (Objects.nonNull(obj)) {
//            log.info("进入了转换层=====");
            UserDTO users = JSON.parseObject(JSON.toJSONString(obj), UserDTO.class);
            return users;
        }
        return null;
    }


    @Override
    public void updateUserInfo(SprayUsers sprayUsers,String key) {
        sprayUsersMapper.updateById(sprayUsers);
        SprayUsers sprayUsers1 = sprayUsersMapper.selectById(sprayUsers.getId());
        redisTemplate.opsForValue().set(RedisKeyConstant.USER_HEAD + key, sprayUsers1);
        redisTemplate.expire(key, timeout, TimeUnit.MINUTES);

    }
}
